#include "attendanceinquiry.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QHeaderView>
#include <QDebug>

#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QTextCodec>
AttendanceInquiry::AttendanceInquiry(QWidget *parent) : QWidget(parent)
{
    // 初始化UI组件
    idLineEdit = new QLineEdit(this);
    nameLineEdit = new QLineEdit(this);
    dateEdit = new QDateEdit(QDate::currentDate(), this);
    queryButton = new QPushButton("查询", this);
    exportButton = new QPushButton("导出Excel", this);
    tableView = new QTableView(this);
    statusLabel = new QLabel("共查询到 0 条记录", this);

    // 初始化数据模型
    m_model = new QStandardItemModel(this);

    // 设置UI
    setupUI();

    // 连接信号槽
    connect(queryButton, &QPushButton::clicked, this, &AttendanceInquiry::onQueryButtonClicked);
    connect(exportButton, &QPushButton::clicked, this, &AttendanceInquiry::onExportButtonClicked);
}

AttendanceInquiry::~AttendanceInquiry()
{
    // 自动删除子对象，无需手动释放
}

void AttendanceInquiry::setupUI()
{
    // 主布局
    QVBoxLayout *mainLayout = new QVBoxLayout(this);

    // 查询条件区域
    QFormLayout *formLayout = new QFormLayout();
    formLayout->addRow("员工ID:", idLineEdit);
    formLayout->addRow("员工姓名:", nameLineEdit);

    // 日期选择设置
    dateEdit->setDisplayFormat("yyyy-MM");
    dateEdit->setCalendarPopup(true);
    formLayout->addRow("查询月份:", dateEdit);

    // 按钮区域
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addWidget(queryButton);
    buttonLayout->addWidget(exportButton);

    // 表格设置
    QStringList headers = {"员工ID", "姓名", "部门", "打卡时间", "类型", "状态", "迟到分钟", "早退分钟"};
    m_model->setHorizontalHeaderLabels(headers);
    tableView->setModel(m_model);
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    tableView->verticalHeader()->hide();

    // 添加到主布局
    mainLayout->addLayout(formLayout);
    mainLayout->addLayout(buttonLayout);
    mainLayout->addWidget(tableView);
    mainLayout->addWidget(statusLabel);

    // 设置窗口属性
    setWindowTitle("考勤记录查询");
    resize(800, 600);

    // 样式设置
    setStyleSheet(R"(
        QWidget {
            font-family: "Microsoft YaHei";
            font-size: 12px;
        }
        QTableView {
            border: 1px solid #ddd;
            gridline-color: #eee;
        }
        QHeaderView::section {
            background-color: #f5f5f5;
            padding: 5px;
            border: none;
            border-bottom: 1px solid #ddd;
        }
        QPushButton {
            padding: 5px 10px;
            min-width: 80px;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 3px;
        }
        QPushButton:hover {
            background-color: #e0e0e0;
        }
        QLineEdit, QDateEdit {
            padding: 3px;
            border: 1px solid #ccc;
            min-width: 150px;
        }
    )");
}


void AttendanceInquiry::onQueryButtonClicked()
{
    QString employeeID = idLineEdit->text().trimmed();
    QString name = nameLineEdit->text().trimmed();
    QString yearMonth = dateEdit->date().toString("yyyy-MM");

    if(employeeID.isEmpty() && name.isEmpty()) {
        QMessageBox::warning(this, "提示", "请输入员工ID或姓名");
        return;
    }

    QString jsonStr = queryAttendanceRecords(employeeID, name, yearMonth);
    QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());
    displayQueryResults(doc.array());
}


void AttendanceInquiry::onExportButtonClicked()
{
    if(m_model->rowCount() == 0) {
        QMessageBox::warning(this, "提示", "没有可导出的数据");
        return;
    }

    QString yearMonth = dateEdit->date().toString("yyyy-MM");
    QString employeeID = idLineEdit->text().trimmed();
    QString name = nameLineEdit->text().trimmed();

    // 生成默认文件名
    QString defaultName = QString("%1%2_%3考勤.csv")
                        .arg(employeeID.isEmpty() ? "" : employeeID + "_")
                        .arg(name.isEmpty() ? "" : name + "_")
                        .arg(yearMonth);

    // 获取保存路径
    QString filePath = QFileDialog::getSaveFileName(
        this,
        "导出考勤报表",
        QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + defaultName,
        "CSV文件 (*.csv);;所有文件 (*.*)"
    );

    if(filePath.isEmpty()) return;

    // 确保文件扩展名是.csv
    if(!filePath.endsWith(".csv", Qt::CaseInsensitive)) {
        filePath += ".csv";
    }

    QString jsonStr = queryAttendanceRecords(employeeID, name, yearMonth);
    QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());

    if(doc.isNull() || !doc.isArray()) {
        QMessageBox::warning(this, "错误", "无法解析查询结果为JSON数组");
        return;
    }

    if(exportToCsv(filePath, doc.array())) {
        // 添加使用建议
        QMessageBox::information(this, "导出成功",
            "报表已成功导出！\n\n"
            "打开提示：\n"
            "1. 使用Excel打开时请选择【数据】->【获取数据】->【从文本/CSV】\n"
            "2. 选择文件后设置编码为UTF-8，分隔符为制表符\n"
            "文件位置：\n" + filePath);
    } else {
        QMessageBox::warning(this, "错误", "报表导出失败!");
    }
}

bool AttendanceInquiry::exportToCsv(const QString &filePath, const QJsonArray &records)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "无法打开文件:" << file.errorString();
        return false;
    }

    QTextStream out(&file);
    // 确保使用UTF-8编码
    out.setCodec("UTF-8");
    out.setGenerateByteOrderMark(true);  // 添加BOM标记

    // 1. 使用直接的UTF-8中文表头（避免编译环境影响）
    out << QString::fromUtf8("日期\t员工ID\t姓名\t部门\t上班时间\t下班时间\t状态\t迟到分钟\t早退分钟\n");

    // 2. 重新设计的按日期+员工分组逻辑
    QMap<QString, QMap<QString, QJsonObject>> employeeRecords;

    // 首先收集所有唯一日期
    QSet<QString> allDates;
    for (const QJsonValue &val : records) {
        QJsonObject record = val.toObject();
        QString date = record["attendaceTime"].toString().left(10);
        allDates.insert(date);
    }

    // 初始化每个员工的所有日期条目
    for (const QJsonValue &val : records) {
        QJsonObject record = val.toObject();
        QString empID = record["employeeID"].toString();
        QString name = record["name"].toString();
        QString dept = record["department"].toString();

        if (!employeeRecords.contains(empID)) {
            employeeRecords[empID] = QMap<QString, QJsonObject>();

            // 为所有日期创建空记录
            for (const QString &date : allDates) {
                QJsonObject empRecord;
                empRecord["employeeID"] = empID;
                empRecord["name"] = name;
                empRecord["department"] = dept;
                empRecord["date"] = date;
                empRecord["check_in"] = "未打卡";
                empRecord["check_out"] = "未打卡";
                empRecord["status"] = "absent";  // 默认缺勤
                empRecord["lateMinutes"] = 0;
                empRecord["earlyMinutes"] = 0;

                employeeRecords[empID][date] = empRecord;
            }
        }
    }

    // 3. 填充实际打卡数据
    for (const QJsonValue &val : records) {
        QJsonObject record = val.toObject();
        QString date = record["attendaceTime"].toString().left(10);
        QString empID = record["employeeID"].toString();
        int checkType = record["checkType"].toInt();
        QString time = record["attendaceTime"].toString().mid(11, 8);

        if (!employeeRecords.contains(empID) || !employeeRecords[empID].contains(date)) {
            qWarning() << "无效记录: empID" << empID << "date" << date;
            continue;
        }

        QJsonObject &empRecord = employeeRecords[empID][date];

        if (checkType == 1) { // 上班打卡
            empRecord["check_in"] = time;
            empRecord["status"] = record["status"].toString();
            empRecord["lateMinutes"] = record["lateMinutes"].toInt();
        }
        else if (checkType == 2) { // 下班打卡
            empRecord["check_out"] = time;
            empRecord["status"] = record["status"].toString();
            empRecord["earlyMinutes"] = record["earlyMinutes"].toInt();
        }
    }

    // 4. 改进的日期排序和输出
    QList<QString> sortedDates = allDates.values();
    std::sort(sortedDates.begin(), sortedDates.end(), [](const QString &a, const QString &b) {
        return QDate::fromString(a, "yyyy-MM-dd") < QDate::fromString(b, "yyyy-MM-dd");
    });

    // 写入分组后的数据
    for (const QString &date : sortedDates) {
        for (auto it = employeeRecords.begin(); it != employeeRecords.end(); ++it) {
            if (!it.value().contains(date)) continue;

            QJsonObject record = it.value()[date];

            // 转换状态为中文
            QString status = record["status"].toString();
            QString statusCN = QString::fromUtf8("未知");
            if (status == "normal") statusCN = QString::fromUtf8("正常");
            else if (status == "late") statusCN = QString::fromUtf8("迟到");
            else if (status == "early") statusCN = QString::fromUtf8("早退");
            else if (status == "absent") statusCN = QString::fromUtf8("缺勤");

            // 使用UTF-8写入，避免编译器编码问题
            out << record["date"].toString() << "\t"
                << record["employeeID"].toString() << "\t"
                << QString::fromUtf8(record["name"].toString().toUtf8().data()) << "\t"
                << QString::fromUtf8(record["department"].toString().toUtf8().data()) << "\t"
                << record["check_in"].toString() << "\t"
                << record["check_out"].toString() << "\t"
                << statusCN << "\t"
                << record["lateMinutes"].toInt() << "\t"
                << record["earlyMinutes"].toInt() << "\n";
        }
    }

    file.close();
    return true;
}

QString AttendanceInquiry::queryAttendanceRecords(const QString &employeeID, const QString &name, const QString &yearMonth)
{
    QJsonArray recordsArray;

    // 初始化数据库连接
        if (!QSqlDatabase::database().isValid()) {
            QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

            if (!db.open()) {
                qCritical() << "无法打开数据库:" << db.lastError().text();
                QMessageBox::critical(nullptr, "错误", "数据库连接失败");
                return "";
            }
        }

    QSqlQuery query;
    QString sql = "SELECT employeeID, name, department, "
                  "attendaceTime, checkType, status, "
                  "lateMinutes, earlyMinutes "
                  "FROM attendance "
                  "WHERE strftime('%Y-%m', attendaceTime) = :yearMonth ";

    if (!employeeID.isEmpty()) {
        sql += "AND employeeID = :employeeID ";
    } else if (!name.isEmpty()) {
        sql += "AND name LIKE :name ";
    }

    sql += "ORDER BY attendaceTime";

    query.prepare(sql);
    query.bindValue(":yearMonth", yearMonth);

    if (!employeeID.isEmpty()) {
        query.bindValue(":employeeID", employeeID);
    } else if (!name.isEmpty()) {
        query.bindValue(":name", "%" + name + "%");
    }

    if (!query.exec()) {
        qDebug() << "Query failed:" << query.lastError().text();
        return "[]";
    }

    while (query.next()) {
        QJsonObject record;
        record["employeeID"] = query.value("employeeID").toString();
        record["name"] = query.value("name").toString();
        record["department"] = query.value("department").toString();
        record["attendaceTime"] = query.value("attendaceTime").toDateTime().toString("yyyy-MM-dd hh:mm:ss");
        record["checkType"] = query.value("checkType").toInt();

        QString status = query.value("status").toString();
        record["status"] = status;

        // 根据状态设置迟到或早退分钟数
        if (status == "late") {
            record["lateMinutes"] = query.value("lateMinutes").toInt();
            record["earlyMinutes"] = 0;
        } else if (status == "early") {
            record["earlyMinutes"] = query.value("earlyMinutes").toInt();
            record["lateMinutes"] = 0;
        } else {
            record["lateMinutes"] = 0;
            record["earlyMinutes"] = 0;
        }

        recordsArray.append(record);
    }

    QJsonDocument doc(recordsArray);
    return doc.toJson();
}
void AttendanceInquiry::displayQueryResults(const QJsonArray &records)
{
    m_model->removeRows(0, m_model->rowCount());

    for(const QJsonValue &value : records) {
        QJsonObject obj = value.toObject();
        QList<QStandardItem*> row;

        // 获取完整的打卡时间字符串（原格式：yyyy-MM-dd hh:mm:ss）
        QString fullTime = obj["attendaceTime"].toString();

        row << new QStandardItem(obj["employeeID"].toString());
        row << new QStandardItem(obj["name"].toString());
        row << new QStandardItem(obj["department"].toString());
        row << new QStandardItem(fullTime); // 显示完整时间（年月日时分秒）
        row << new QStandardItem(obj["checkType"].toInt() == 1 ? "上班" : "下班");

        // 状态显示优化
        QString status = obj["status"].toString();
        QString statusText;
        if(status == "normal") statusText = "正常";
        else if(status == "late") statusText = "迟到";
        else if(status == "early") statusText = "早退";
        else if(status == "absent") statusText = "缺勤";
        else statusText = status;

        row << new QStandardItem(statusText);
        row << new QStandardItem(QString::number(obj["lateMinutes"].toInt()));
        row << new QStandardItem(QString::number(obj["earlyMinutes"].toInt()));

        m_model->appendRow(row);
    }

    // 调整列宽以适应内容
    tableView->resizeColumnsToContents();

    // 特别加宽时间列（因为现在显示完整时间）
    tableView->setColumnWidth(3, 150); // 第4列（索引3）是时间列

    statusLabel->setText(QString("共查询到 %1 条记录").arg(records.size()));
}


